//
//  ZZCEmoticonTools.swift
//  weibo
//
//  Created by zhangzuchao on 2017/4/7.
//  Copyright © 2017年 zhangZuChao. All rights reserved.
//

import UIKit
import YYModel

//  每页显示20个表情
let NumberOfPage = 20

//  最近表情归档和解档路径
let RecentEmoticonArrayPath = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last! as NSString).appendingPathComponent("recentEmotionArray.archive")

class ZZCEmoticonTools: NSObject {
    
    //  单例全局访问点
    static let sharedTools: ZZCEmoticonTools = ZZCEmoticonTools()

    //  构造函数私有化
    private override init() {
        super.init()
    }
    
    //  创建emoticonsBundle对象
    lazy var emoticonBundle: Bundle = {
        //  获取bundle的路径
        let bundlePath = Bundle.main.path(forResource: "Emoticons.bundle", ofType: nil)!
        //  根据路径创建bundle对象
        let bundle = Bundle(path: bundlePath)!
        return bundle
    }()
    
    //  默认表情
    fileprivate lazy var defualtEmoticonArray: [ZZCEmoticon] = {
        return self.getEmoticonArray(folderName: "default", fileName: "info.plist")
    }()
    //  emoji表情
    fileprivate lazy var emojiEmoticonArray: [ZZCEmoticon] = {
        return self.getEmoticonArray(folderName: "emoji", fileName: "info.plist")
    }()
    //  浪小花表情
    fileprivate lazy var lxhEmoticonArray: [ZZCEmoticon] = {
        return self.getEmoticonArray(folderName: "lxh", fileName: "info.plist")
    }()
    
    //  最近表情
    fileprivate lazy var recentEmoticonArray: [ZZCEmoticon] = {
        
        if let localRecentEmoticonArray = self.loadRecentEmoticonArray() {
            //  有本地最近表情数据
            return localRecentEmoticonArray
        } else {
            //  没有本地表情数据
            let recentEmotionArray = [ZZCEmoticon]()
            return recentEmotionArray
        }
    }()
    
    //  三维数组
    //  准备表情视图所需要的数组
    lazy var allEmoticonArray: [[[ZZCEmoticon]]] = {
        
        return [
            //  放入不同的二维数组
            //  最近表情,只有一页
            [self.recentEmoticonArray],
            //  默认表情
            self.section(emoticonArray: self.defualtEmoticonArray),
            //  emoji表情
            self.section(emoticonArray: self.emojiEmoticonArray),
            //  浪小花
            self.section(emoticonArray: self.lxhEmoticonArray),
            ]
    }()

    
    //  获取最近表情数据
    func loadRecentEmoticonArray() -> [ZZCEmoticon]? {
        //  解档数据
        let localArray = NSKeyedUnarchiver.unarchiveObject(withFile: RecentEmoticonArrayPath) as? [ZZCEmoticon]
        return localArray
    }
    
    //  根据表情描述获取表情模型
    func selectedEmoticon(chs: String) -> ZZCEmoticon? {
        
        //  遍历默认表情数组查找表情模型
        for emoticon in defualtEmoticonArray {
            if emoticon.chs == chs {
                return emoticon
            }
        }
        //  遍历浪小花表情数组查找表情模型
        for emoticon in lxhEmoticonArray {
            if emoticon.chs == chs {
                return emoticon
            }
        }
        
        return nil
    }
    
    //  保存点击的表情模型
    func saveRecentEmoticonArray(emoticon: ZZCEmoticon) {
        //  判断最近表情里面是否有要添加的表情模型
        for (i,currentEmoticon) in recentEmoticonArray.enumerated() {
            if emoticon.type == "0" {
                //  图片表情,判断chs是否相同
                if currentEmoticon.chs == emoticon.chs {
                    //  2. 如果有这个要添加的表情模型,从最近表情中删除
                    //  有相同表情,删除该表情
                    recentEmoticonArray.remove(at: i)
                    break
                }
            } else {
                //  emoji表情, 判断code是否相同
                if currentEmoticon.code == emoticon.code {
                    //   如果有这个要添加的表情模型,从最近表情中删除
                    //  有相同表情,删除该表情
                    recentEmoticonArray.remove(at: i)
                    break
                }
            }
        }
        
        //   把点击的表情添加到数组的第一个元素的位置(最近使用的表情发到最前面)
        recentEmoticonArray.insert(emoticon, at: 0)
        
        if recentEmoticonArray.count > 20 {
            //  如果最近表情个数大于20个删除最后的一个元素
            recentEmoticonArray.removeLast()
        }
        
        //   把allEmoticonArray的最近表情数据进行修改
        allEmoticonArray[0][0] = recentEmoticonArray
        
        //   把最近表情进行保存(归档)
        NSKeyedArchiver.archiveRootObject(recentEmoticonArray, toFile: RecentEmoticonArrayPath)
        
        
    }
    
    //  一维数组
    //  根据传入的文件夹名和文件的名字获取对应的表情数据
    fileprivate func getEmoticonArray(folderName: String, fileName: String) -> [ZZCEmoticon] {
        //  获取表情数据的子路径
        let subPath = folderName + "/" + fileName
        let path = self.emoticonBundle.path(forResource: subPath, ofType: nil)!
        //  读取info.plist文件数据
        let dicArray = NSArray(contentsOfFile: path) as! [[String: Any]]
        //  使用YYModel完成数组字典转成数组模型
        let modelArray = NSArray.yy_modelArray(with: ZZCEmoticon.self, json: dicArray) as! [ZZCEmoticon]

        //图片需要全路径才能访问到,因为不在assets里面,需要添加路径并赋值回去
        for model in modelArray {
            if model.type == "0" {
                //  图片表情全路径
                let path = emoticonBundle.path(forResource: folderName, ofType: nil)! + "/" + model.png!
                //  设置图片的全路径
                model.path = path
                //  图片对应的文件
                model.folderName = folderName
            }
        }
        
        return modelArray
    }
    //  二维数组
    //  拆分20个图片每页
    fileprivate func section(emoticonArray: [ZZCEmoticon]) -> [[ZZCEmoticon]] {
        //  根据传入的表情个数计算显示页数
        let pageCount = (emoticonArray.count - 1) / NumberOfPage + 1
        var tempArray = [[ZZCEmoticon]]()
        //  遍历页数截取表情数组
        for i in 0..<pageCount {
            //  开始截取的索引
            let loc = i * NumberOfPage
            //  截取的长度
            var len = NumberOfPage
            
            if loc + len > emoticonArray.count {
                //  超出范围, 截取剩余的个数
                len = emoticonArray.count - loc
                
            }
            
            //  截取的范围
            let range = NSMakeRange(loc, len)
            //  根据范围截取子数组
            let subArray = (emoticonArray as NSArray).subarray(with: range) as! [ZZCEmoticon]
            tempArray.append(subArray)
        }
        return tempArray
    }
    
    
    
    }
